package com.itboye.api.model;


import com.itboye.config.GlobalConfig;
import com.itboye.system.crypt.ByDataCrypt;
import com.itboye.system.crypt.JsonCrypt;
import com.itboye.system.exception.ByBaseException;
import com.itboye.system.helper.ByDateHelper;

import java.io.UnsupportedEncodingException;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;

/**
 * 接口请求返回的参数信息
 * Created by hebidu on 16/5/10.
 */
public class ByResponseData {

    /**
     * 获取解压缩后的密文
     * @return
     * @throws UnsupportedEncodingException
     */
    public String getDecryptData() throws UnsupportedEncodingException {
       return ByDataCrypt.decode(this.getData());
    }

    /**
     * 获取解压缩后的map
     * @return
     * @throws UnsupportedEncodingException
     */
    public HashMap<String,String> getDecryptMapData() throws UnsupportedEncodingException {
        String json = getDecryptData();
        return JsonCrypt.readValue(json,HashMap.class);
    }

    @Override
    public String toString() {
        return "ByResponseData{" +
                "clientSecret='" + clientSecret + '\'' +
                ", data='" + data + '\'' +
                ", notifyId='" + notifyId + '\'' +
                ", time='" + time + '\'' +
                ", type='" + type + '\'' +
                ", alg='" + alg + '\'' +
                ", sign='" + sign + '\'' +
                '}';
    }

    public String getClientSecret() {
        return clientSecret;
    }

    public void setClientSecret(String clientSecret) {
        this.clientSecret = clientSecret;
    }

    public String getData() {
        return data;
    }

    public void setData(String data) {
        this.data = data;
    }

    public String getNotifyId() {
        return notifyId;
    }

    public void setNotifyId(String notifyId) {
        this.notifyId = notifyId;
    }

    public String getTime() {
        return time;
    }

    public void setTime(String time) {
        this.time = time;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public String getAlg() {
        return alg;
    }

    public void setAlg(String alg) {
        this.alg = alg;
    }

    public String getSign() {
        return sign;
    }

    public void setSign(String sign) {
        this.sign = sign;
    }

    public String getClientId() {
        return clientId;
    }

    public void setClientId(String clientId) {
        this.clientId = clientId;
    }

    private String clientId;
    private String clientSecret;
    private String data;
    private String notifyId;
    private String time;
    private String type;
    private String alg;
    private String sign;


    private ByResponseData(){
        this.clientSecret = "";
        this.data = "";
        this.notifyId = "";
        this.time = "";
        this.type = "";
        this.alg = "";
        this.sign = "";
    }

    public static ByResponseData DEFAULT(String msg) throws UnsupportedEncodingException, ByBaseException {
        ByResponseData responseData = ByResponseData.fail("-1",msg, GlobalConfig.DEFAULT_CLIENT_SECRET,GlobalConfig.DEFAULT_NOTIFY_ID);
        responseData.setClientId(GlobalConfig.DEFAULT_CLIENT_ID);
        return responseData;
    }

    /**
     * 错误返回
     * @param code
     * @param msg
     * @param clientId
     * @param notifyId
     * @return
     * @throws UnsupportedEncodingException
     * @throws NoSuchAlgorithmException
     */
    public static ByResponseData fail(String code,String msg,String clientSecret,String notifyId) throws ByBaseException, UnsupportedEncodingException {
        ByInnerResponseData innerData = new ByInnerResponseData(code,msg,notifyId);
        String innerJson = innerData.toJson();
        return ByResponseData.done(false,ByDataCrypt.encodeData(innerJson),clientSecret,notifyId);
    }

    /**
     * 完成返回
     * @param isSuccess 是否调用成功
     * @param data      加密过的数据内容
     * @param clientSecret 秘钥,作签名用到,不会返回给客户端
     * @param notifyId  该请求id
     * @return
     * @throws ByBaseException
     */
    public static  ByResponseData done(Boolean isSuccess,String data,String clientSecret,String notifyId) throws ByBaseException {
        ByResponseData respData = new ByResponseData();

        String time = ByDateHelper.getCurrentTimeStamp().toString();
        String type = "T";
        if(!isSuccess){
            type = "F";
        }

        String alg = "md5";

        respData.setData(data);
        respData.setAlg(alg);
        respData.setClientSecret(clientSecret);
        respData.setNotifyId(notifyId);
        respData.setTime(time);
        respData.setType(type);

        HashMap<String,String> params = new HashMap<String,String>();
        params.put("client_secret",clientSecret);
        params.put("data",data);
        params.put("notify_id",notifyId);
        params.put("time",time);
        params.put("type",type);
        params.put("alg",alg);

        String sign = null;
        try {
            sign = ByDataCrypt.sign(params);
        } catch (UnsupportedEncodingException e) {
            throw new ByBaseException(e.getLocalizedMessage());
        } catch (NoSuchAlgorithmException e) {
            throw new ByBaseException(e.getLocalizedMessage());
        }
        respData.setSign(sign);


        return respData;
    }

    public String toJson() throws UnsupportedEncodingException,NoSuchAlgorithmException {

        HashMap<String,String> params = new HashMap<String,String>();

        HashMap<String,String> signParams = new HashMap<String, String>();

        String time = "" + ByDateHelper.getCurrentTimeStamp();

        signParams.put("client_secret",getClientSecret());
        signParams.put("notify_id",getNotifyId());
        signParams.put("time",time);
        signParams.put("data",getData());
        signParams.put("type",getType());
        signParams.put("alg",getAlg());

        String sign = ByDataCrypt.sign(signParams);

        params.put("client_id", clientId);
        params.put("data",data);
        params.put("notify_id",notifyId);
        params.put("time",time);
        params.put("type",type);
        params.put("sign",sign);

        return JsonCrypt.toJson(params);
    }

}
